﻿
/*============== simpleIRC - http://matthias.van-eeghem.com/ ==============*
 *                                                                         *
 *  File: UserInterface.cs                                                 *
 *  Project: simpleIRC                                                     *
 *  Author(s): Matthias Van Eeghem <matthias@van-eeghem.com>               *
 *                                                                         *
 * ========================================================================*
 *                                                                         *
 *  This program is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation, either version 3 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 *                                                                         *
===========================================================================*/

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using System.Xml;
using System.Xml.XPath;

namespace simpleIRC.UI
{
    /// <summary>
    /// The UserInterface class
    /// </summary>
    public class UserInterface
    {
        private MainWindow mainWindow = null;
		
        /// <summary>
        /// The constructor of the UserInterface class.
        /// </summary>
        /// <param name="parentWindow">The reference to the main window object</param>
        public UserInterface(MainWindow parentWindow)
        {
            mainWindow = parentWindow;
        }

        /// <summary>
        /// This function adds a context menu to a TreeViewItem
        /// </summary>
        /// <param name="treeViewItem">The treeviewitem to add the context menu to</param>
        /// <param name="optionName">The name of the option</param>
        /// <param name="functionToCall">The function that should be called when clicking an option</param>

        public void AddRightClickEvent(ref TreeViewItem treeViewItem, string optionName, RoutedEventHandler functionToCall)
        {
            ContextMenu RightClickMenu = new ContextMenu();
            MenuItem MenuItem = new MenuItem();

            MenuItem.Header = optionName;
            MenuItem.Click += new RoutedEventHandler(functionToCall);

            treeViewItem.ContextMenu = RightClickMenu;
            treeViewItem.ContextMenu.Items.Add(MenuItem);
        }

        /// <summary>
        /// This function adds the timestamp in before an outputline
        /// </summary>
        /// <param name="formatLine">The line to format (a reference to make things easier)</param>
        
        public void FormatTimestamp(ref string formatLine)
        {
            DateTime CurrentTime = DateTime.Now;

            // Get the timestamp from the settings.xml file
            string TimeStamp = mainWindow.Config.Settings["Timestamp"];

            // Replace all the strings with the current time
            TimeStamp = TimeStamp.Replace("hour", CurrentTime.Hour.ToString().PadLeft(2, '0'));
            TimeStamp = TimeStamp.Replace("minute", CurrentTime.Minute.ToString().PadLeft(2, '0'));
            TimeStamp = TimeStamp.Replace("second", CurrentTime.Second.ToString().PadLeft(2, '0'));
            TimeStamp = TimeStamp.Replace("year", CurrentTime.Year.ToString());
            TimeStamp = TimeStamp.Replace("month", CurrentTime.Month.ToString().PadLeft(2, '0'));
            TimeStamp = TimeStamp.Replace("day", CurrentTime.Day.ToString().PadLeft(2, '0'));

            formatLine = TimeStamp + formatLine;
        }

        /// <summary>
        /// This method sends a message to the current window the user is looking at, this could be a query window, a channel window or server window.
        /// </summary>
        /// <param name="message">The message to send</param>
        /// <param name="appendTimestamp">If this bool is set to true, the method prepends a timestamp before the string</param>

        public void SendTextToCurrentWindow(string message, bool appendTimestamp = true)
        {
            if (mainWindow.CurrentChannelWindow != -1 && mainWindow.CurrentQueryWindow == -1)
            {
                ChannelWindow.List[mainWindow.CurrentChannelWindow].SendText(message, appendTimestamp);
            }

            if (mainWindow.CurrentChannelWindow == -1 && mainWindow.CurrentQueryWindow != -1)
            {
                QueryWindow.List[mainWindow.CurrentQueryWindow].SendText(message, appendTimestamp);
            }

            if (mainWindow.CurrentChannelWindow == -1 && mainWindow.CurrentQueryWindow == -1)
            {
                ServerWindow.List[mainWindow.CurrentServerWindow].SendText(message, appendTimestamp);
            }
        }


        /// <summary>
        /// This method returns the header of the current TreeViewItem in the UsersTreeView as a string
        /// </summary>
        /// <returns></returns>

        internal string GetCurrentTreeViewItemHeaderWithoutRights()
        {
            TreeViewItem SelectedItem = new TreeViewItem();
            SelectedItem = mainWindow.UsersTreeView.SelectedItem as TreeViewItem;

            string UserName = "";

            if (SelectedItem != null)
            {
                UserName = SelectedItem.Header.ToString();

                // Remove the rights
                if (UserName[0] == '~' || UserName[0] == '&' || UserName[0] == '@' || UserName[0] == '%' || UserName[0] == '+')
                    UserName = UserName.Remove(0, 1);
            }

            return UserName;
        }

        /// <summary>
        /// This is called when the user right clicks on another user
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        
        internal void ContextMenu_CloseQueryWindow(object sender, EventArgs e)
        {
            TreeViewItem SelectedItem = new TreeViewItem();
            SelectedItem = mainWindow.ChannelsTreeView.SelectedItem as TreeViewItem;

            if (SelectedItem != null)
            {
                string UserName = SelectedItem.Header.ToString();

                Query Query = Core.GetQueryObject(UserName, mainWindow.CurrentServerWindow);

                QueryWindow.List[Query.Index].Remove();
                Query.Remove();
            }
        }

        /// <summary>
        /// This is called when the user right clicks on another user
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        internal void ContextMenu_CloseAllQueries(object sender, EventArgs e)
        {
            ServerWindow.List[mainWindow.CurrentServerWindow].RemoveQueryList();
        }

        /// <summary>
        /// This is called when the user right clicks on a channel.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        internal void ContextMenu_PartChannel(object sender, EventArgs e)
        {
            TreeViewItem SelectedItem = new TreeViewItem();
            SelectedItem = mainWindow.ChannelsTreeView.SelectedItem as TreeViewItem;

            if (SelectedItem != null)
            {
                TreeViewItem ParentItem = new TreeViewItem();
                ParentItem = SelectedItem.Parent as TreeViewItem;

                // If the parent item isn't null, the user selected a channel window.
                if (ParentItem != null)
                {
                    string ChannelName = SelectedItem.Header.ToString();
                    string ServerName = ParentItem.Name.ToString();

                    // Get the channel and server index.
                    Server Server = Core.GetServerObject(ServerName);
                    Channel Channel = Core.GetChannelObject(ChannelName, Server.Index);

                    ChannelWindow.List[Channel.Index].Remove();
                    Channel.Part();
                }
            }
        }

        /// <summary>
        /// This is called when the user right clicks on a channel.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        
        public void ContextMenu_PartServer(object sender, EventArgs e)
        {
            TreeViewItem SelectedItem = new TreeViewItem();
            SelectedItem = mainWindow.ChannelsTreeView.SelectedItem as TreeViewItem;

            if (SelectedItem != null)
            {
                string ServerName = SelectedItem.Name.ToString();
                Server Server = Core.GetServerObject(ServerName);

                // If we're connected to that server, inform the user
                if (Server.ConnectionState > Core.eConnectionStates.Disconnected)
                {
                    MessageBoxResult CloseDialog = MessageBox.Show("You're still connected to that server! Are you sure you wish to close that server window?", "Confirm Close", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes);

                    // He wants to close the application, disconnect all servers first
                    if (CloseDialog == MessageBoxResult.Yes)
                    {
                        Server.Disconnect(Server.Nick);
                        ServerWindow.List[Server.Index].Remove();
                    }
                }
            }
        }

        /// <summary>
        /// This method is called when the user clicks on the Voice subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Voice(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " +v " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Devoice subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Devoice(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " -v " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Halfop subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Halfop(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " +h " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Dehalfop subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Dehalfop(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " -h " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Op subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Op(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " +o " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Deop subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Deop(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " -o " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Superop subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Superop(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " +a " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Desuperop subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Desuperop(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " -a " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Owner subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Owner(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " +q " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Deowner subitem in the Level list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Level_Deowner(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("MODE " + Core.ChannelList[mainWindow.CurrentChannelWindow].Name + " -q " + UserName);
        }

        /// <summary>
        /// This method is called when the user clicks on the Ping subitem in the Info list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Info_Ping(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
            {
                int EpochTime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

                Core.ServerList[mainWindow.CurrentServerWindow].SendData("PRIVMSG " + UserName + " :PING " + EpochTime.ToString() + "");
            }
        }

        /// <summary>
        /// This method is called when the user clicks on the Time subitem in the Info list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Info_Time(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("PRIVMSG " + UserName + " :TIME");
        }

        /// <summary>
        /// This method is called when the user clicks on the Version subitem in the Info list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Info_Version(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("PRIVMSG " + UserName + " :VERSION");
        }

        /// <summary>
        /// This method is called when the user clicks on the Whois subitem in the Info list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_Info_Whois(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
                Core.ServerList[mainWindow.CurrentServerWindow].SendData("WHOIS " + UserName);
        }

        /// <summary>
        /// This is called when the user right clicks on another user
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        public void ContextMenu_QueryUser(object sender, EventArgs e)
        {
            string UserName = GetCurrentTreeViewItemHeaderWithoutRights();

            if (UserName != "")
            {
                if (Core.GetQueryObject(UserName, mainWindow.CurrentServerWindow) == null)
                {
                    QueryList.ListOfQueries[mainWindow.CurrentServerWindow].QueryListTreeViewItem.Visibility = Visibility.Visible;

                    Query Query = new Query(mainWindow.CurrentServerWindow, UserName);
                    new QueryWindow(UserName, mainWindow.CurrentServerWindow, (Core.QueryList.Count - 1), mainWindow).Create();
                }
            }
        }
    }
}
